#ifndef RENDERABLESPRITES_H_INCLUDED
#define RENDERABLESPRITES_H_INCLUDED

#include <boost/pool/object_pool.hpp>
#include <boost/pool/pool.hpp>
#include <General/cvMemory.h>
#include <list>
#include <vector>


/// pre decl
namespace cvImmediateModeRenderer
{
	class RenderableSprites;
	class Sprite;
};
#include "../cvIRender.h"
#include "../cvIPrimitives.h"

namespace cvImmediateModeRenderer
{
	struct sprite_struct
	{
		cvVert v[4];
		cvVert uv[4];
		RGBAf c[4];
	} HINT_PACKED;

	class Sprite : public cvRenderInterface::Sprite
	{
		public:
			Sprite * uvs(const cvVert &uv1, const cvVert &uv2, const cvVert &uv3, const cvVert &uv4);
			Sprite * trans(const cvVert &pos, const cvVert &offset, float angle, float wscale, float hscale);
			Sprite * color(RGBAf col);

			void uvs(cvVert *uv1, cvVert *uv2, cvVert *uv3, cvVert *uv4);
			void color(size_t index, RGBAf *col);
	};

	class RenderableSprites : public cvRenderInterface::TexturedBatch<cvRenderInterface::Sprite>
	{
		public:
			RenderableSprites();
			virtual ~RenderableSprites();

			/// Pool where RenderableSprite rips out of its memory.
			static boost::pool<> m_spritebatch_pool;
			void * operator new(size_t size);
			void operator delete(void * ptr);

			void prepareDraw();

			void draw();

			/// maps primitives to array.
			void map(cvRenderInterface::Sprite ** array, size_t count);

			/// drops primitives from BatchObject.
			void drop(cvRenderInterface::Sprite ** array, size_t count);

			/// Adds new singleshot primitives - returns temporary primitive.
			cvRenderInterface::Sprite * mapSingleshot();

			/// drop all primitives, but don't release memory.
			void flush();

			/// returns count of primitives in this BatchObject
			size_t size();

			int renderableType();

			/// set the texture to be used for ALL PRIMITIVES.
			void setTexture(ImageObject * imgobj);

		private:
			typedef std::vector<sprite_struct, cvPoolAllocator<sprite_struct>::CON> sprdat_vector_t;
			typedef std::vector<sprite_struct, cvPoolAllocator<sprite_struct>::CON> sprdat_list_t;
			typedef std::list<Sprite*, cvPoolAllocator<Sprite*>::RAN> mod_list_t;

			sprdat_list_t m_storgate_sprites;	// all sprites.
			sprdat_vector_t m_draw_sprites;		// visible sprites.
			size_t m_rendercount;

			mod_list_t m_modifyhandles;

			boost::pool<> m_handlepool;
	};

};

#endif // RENDERABLESPRITES_H_INCLUDED
